import ConfigParser
import time
import re
import base64
import httplib
import GeoIP

from string import lower
from urlparse import urlparse 

from proxy import Proxy 
from threading import Thread
from database import Database

class CheckProxy(Thread):
	def __init__(self, proxy_id, check_url, check_values):
		Thread.__init__(self)
		self.proxy = Proxy(proxy_id)
		self.check_url_str = check_url
		self.check_url = urlparse(check_url)
		self.check_values = check_values.split(',')
		self.chopitodata = re.compile("\n===\sSTART\sCHOPITO\sDATA\s===\n(?P<data>[A-Za-z0-9=]+)\n===\sEND\sCHOPITO\sDATA\s===\n")

	def run(self):
		print "Checking proxy: " + self.proxy.ip + ":" + str(self.proxy.port) + " ..."		
		checks = {}
		for value in self.check_values:
			if value == "latency":
				res = self.do_check(value)
				if res.has_key('t2'):
					connecttime = str((res['t1']-res['t0'])*1000)
					gettime = str((res['t2']-res['t1'])*1000)
					totaltime = str((res['t2']-res['t0'])*1000)
					self.proxy.set_property('latency-connecttime', connecttime)
					self.proxy.set_property('latency-gettime', gettime)
					self.proxy.set_property('latency-totaltime', totaltime)
					checks['latency'] = True
				else:
					checks['latency'] = False

			if value == "integrity":
				pass

			if value == "headers":
				res = self.do_check(value)
				if res.has_key('content'):
					data = self.chopitodata.match(res['content'])
					if data:
						try:
							headers = eval(base64.urlsafe_b64decode(data.group('data')), {})
							for header in headers.items():
								name="header-" + lower(re.sub("[^A-Za-z0-9\-_\.]","",header[0]))
								if name == "header-":
									continue
								value=re.sub("[\"']","",header[1])
								self.proxy.set_property(name, value)	
							checks['headers'] = True
						except:
							checks['headers'] = False
					else:
						checks['headers'] = False

			if value == "location":
				try:
					gi = GeoIP.open('/usr/local/share/GeoIP/GeoIPCity.dat', GeoIP.GEOIP_STANDARD)
					gir = gi.record_by_addr(self.proxy.ip)
					for item in gir.items():
						self.proxy.set_property('location-' + item[0], item[1])
					checks['location'] = True
				except:
					print "Error in location check"
					checks['location'] = False
					
		allok = True
		for value in self.check_values:
			if checks.has_key(value):
				if not checks[value]:
					allok = False
					break
		if allok:	
			print "Active"
			self.proxy.set_property('active', True)
		else:
			print "Inactive"
			self.proxy.set_property('active', False)

		self.proxy.set_property('checked', True)

	def do_check(self, check):	
		data = {}
		try:
			data['t0'] = time.time()
			conn = httplib.HTTPConnection(self.proxy.ip, self.proxy.port)
			conn.request("GET", self.check_url_str + "?check=" + check)	
			r = conn.getresponse()	
			data['t1'] = time.time()
			data['code'] = str(r.status)
			data['content'] = r.read()
			conn.close()
			data['t2'] = time.time()
		except Exception, e:
			pass

		return data

if __name__ == '__main__':
	config = ConfigParser.RawConfigParser()
	if config.read("/etc/chopito/chopito.conf") != ['/etc/chopito/chopito.conf']:
		raise NameError, "Config not found"

	if not config.has_section('Database'):
		raise NameError, "Config file: Database not defined"

	while 1:
		if config.get('Database', 'type') == "mysql":
			db = Database()

			if not config.has_section('Checker') or not config.has_option('Checker', 'url'):
				raise NameError, "Config file: Checker, url not found"
				
			if not config.has_option('Checker', 'values'):
#				check_values = "latency"
				check_values = "headers,latency,location"
			else:
				check_values = config.get('Checker', 'values')

			sql = "SELECT idproxy FROM proxys WHERE (active=0 AND checked IS NULL) OR (checked < DATE_SUB(NOW(), INTERVAL 2 HOUR)) LIMIT 50"
			cursor = db.cursor_tuple()
			cursor.execute(sql)
			res = cursor.fetchall()
			checklist = []
			if res:			
				for id in res:
					chk = CheckProxy(str(id[0]), config.get('Checker', 'url'), check_values);
					checklist.append(chk)
					chk.start()
			else:
				print "Sleeping 10 minutes..."
				time.sleep(600)
					
			for checking in checklist:
				chk.join()
				
		else:
			print "config error"
			exit(1)
			
